﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Assets.Scripts.Tcp
{
    public class BlockBuffer<T> : IBlockBuffer<T>
    {
        public T[] Buffer => _Buffer;
        public T[] _Buffer;
        public int Size => Buffer.Length;
        public int ReadPosition { get; private set; }
        public int WritePosition { get; private set; }

        public BlockBuffer(T[] buffer)
        {
            _Buffer = buffer;
        }
        public BlockBuffer(int size)
        {
            _Buffer = new T[size];
        }

        public void MoveReadPositionTo(int index)
        {
            if (index >= Size) throw new IndexOutOfRangeException(string.Format("目标坐标：{0}    最大坐标：{1}", index, Size));
            else if (index <= 0) throw new IndexOutOfRangeException(string.Format("目标坐标：{0}    最小坐标：{1}", index, 0));
            ReadPosition = index;
        }

        public void MoveReadPostion(int length)
        {
            if (ReadPosition + length >= Size) throw new IndexOutOfRangeException(string.Format("目标坐标：{0}    最大坐标：{1}", ReadPosition + length, Size));
            else if (ReadPosition + length < 0) throw new IndexOutOfRangeException(string.Format("目标坐标：{0}    最大坐标：{1}", ReadPosition + length, 0));
            ReadPosition = length;
        }

        public void MoveWritePosition(int length)
        {
            if (WritePosition + length >= Size) throw new IndexOutOfRangeException(string.Format("目标坐标：{0}    最大坐标：{1}", WritePosition + length, Size));
            else if (WritePosition + length < 0) throw new IndexOutOfRangeException(string.Format("目标坐标：{0}    最大坐标：{1}", WritePosition + length, 0));
            WritePosition += length;
        }

        public void MoveWritePostionTo(int index)
        {
            if (index >= Size) throw new IndexOutOfRangeException(string.Format("目标坐标：{0}    最大坐标：{1}", index, Size));
            else if (index <= 0) throw new IndexOutOfRangeException(string.Format("目标坐标：{0}    最小坐标：{1}", index, 0));
            WritePosition = index;
        }

        public T[] Read(int length)
        {
            T[] ret = new T[length];
            _Buffer.CopyTo(ret, ReadPosition, 0, length);
            MoveReadPostion(length);
            return ret;
        }

        public void Read(T[] destinationArray, int destinationIndex, int length)
        {
            _Buffer.CopyTo(destinationArray, ReadPosition, destinationIndex, length);
            MoveReadPostion(length);
        }

        public void ResetIndex()
        {
            ReadPosition = 0;
            WritePosition = 0;
        }

        public void Write(T[] sourceArray)
        {
            Write(sourceArray, 0, sourceArray.Length);
        }

        public void Write(T[] sourceArray, int sourceIndex, int length)
        {
            sourceArray.CopyTo(_Buffer, sourceIndex, WritePosition, sourceArray.Length);
            MoveWritePosition(sourceArray.Length);
        }

        public void Dispose()
        {
            ResetIndex();
            _Buffer = null;
        }
    }
}
